﻿using Microsoft.Practices.Unity;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Ewk.Configuration.UnitTests
{
    [TestClass]
    public class UnityDependencyResolverTests
    {
        [TestMethod, ExpectedException(typeof(ResolutionFailedException))]
        public void When_the_UnityDependencyResolver_is_initialized_without_a_UnityContainer_nothig_can_be_resolved()
        {
            var resolver = new UnityDependencyResolver();
            resolver.Resolve<IDummy>();
        }

        [TestMethod, ExpectedException(typeof(ResolutionFailedException))]
        public void When_the_UnityDependencyResolver_is_initialized_with_a_non_configured_UnityContainer_nothig_can_be_resolved()
        {
            var unityContainer = new UnityContainer();
            var resolver = new UnityDependencyResolver(unityContainer);
            resolver.Resolve<IDummy>();
        }

        [TestMethod]
        public void EnsureIsRegistered_on_UnityDependencyResolver_makes_sure_the_type_can_be_resolved()
        {
            var resolver = new UnityDependencyResolver();
            resolver.EnsureIsRegistered<IDummy, DummyA>();
            var instance = resolver.Resolve<IDummy>();

            Assert.IsInstanceOfType(instance, typeof(IDummy));
            Assert.IsInstanceOfType(instance, typeof(DummyA));
        }

        [TestMethod]
        public void When_the_UnityDependencyResolver_is_initialized_with_a_configured_UnityContainer_the_type_can_be_resolved()
        {
            var unityContainer = new UnityContainer();
            unityContainer.RegisterType<IDummy, DummyA>();

            var resolver = new UnityDependencyResolver(unityContainer);
            var instance = resolver.Resolve<IDummy>();

            Assert.IsInstanceOfType(instance, typeof(IDummy));
            Assert.IsInstanceOfType(instance, typeof(DummyA));
        }

        [TestMethod]
        public void When_the_UnityDependencyResolver_is_initialized_with_a_configured_UnityContainer_types_can_be_resolved_by_name()
        {
            const string nameA = "A";
            const string nameB = "B";

            var unityContainer = new UnityContainer();
            unityContainer.RegisterType<IDummy, DummyA>(nameA);
            unityContainer.RegisterType<IDummy, DummyB>(nameB);

            var resolver = new UnityDependencyResolver(unityContainer);
            var instanceA = resolver.Resolve<IDummy>(nameA);
            var instanceB = resolver.Resolve<IDummy>(nameB);

            Assert.IsInstanceOfType(instanceA, typeof(IDummy));
            Assert.IsInstanceOfType(instanceA, typeof(DummyA));

            Assert.IsInstanceOfType(instanceB, typeof(IDummy));
            Assert.IsInstanceOfType(instanceB, typeof(DummyB));
        }

        interface IDummy
        {
        }

        class DummyA : IDummy
        {
        }

        class DummyB : IDummy
        {
        }
    }
}